﻿using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using Neturion.Dados;
using Neturion.IRepositorios;

namespace Neturion.Repositorios
{
    public class RepositorioProtocolo : IRepositorioProtocolo
    {
        public Protocolo Inserir(Protocolo protocolo)
        {
            foreach (ProtocoloProcedimento protocoloProcedimento in protocolo.ListaProtocoloProcedimento)
            {
                protocoloProcedimento.Protocolo = protocolo;
            }

            GerenciadorBDConfigs.Instance.SessaoAtual().Save(protocolo);
            return protocolo;
        }

        public Protocolo Atualizar(Protocolo protocolo)
        {
            Protocolo tmpProtocolo = ObterPorId(protocolo.ProtocoloId);
            // Atribuicao dos valores do objeto da memoria para o objeto obtido no banco de dados
            tmpProtocolo.Assunto = protocolo.Assunto;
            tmpProtocolo.Codigo = protocolo.Codigo;
            tmpProtocolo.DataCadastro = protocolo.DataCadastro;
            tmpProtocolo.TipoProtocolo = protocolo.TipoProtocolo;
            tmpProtocolo.FuncionarioCadastro = protocolo.FuncionarioCadastro;
            tmpProtocolo.FuncionarioDestino = protocolo.FuncionarioDestino;
            tmpProtocolo.Interlocutor = protocolo.Interlocutor;
            tmpProtocolo.Midia = protocolo.Midia;
            tmpProtocolo.MotivoProtocolo = protocolo.MotivoProtocolo;
            tmpProtocolo.NeturionLog = protocolo.NeturionLog;
            tmpProtocolo.ProtocoloPai = protocolo.ProtocoloPai;
            tmpProtocolo.SetorDestino = protocolo.SetorDestino;
            tmpProtocolo.SituacaoTramiteProtocolo = protocolo.SituacaoTramiteProtocolo;

            tmpProtocolo.ListaProtocoloProcedimento.Clear();
            foreach (ProtocoloProcedimento protocoloProcedimento in protocolo.ListaProtocoloProcedimento)
            {
                tmpProtocolo.AdicionarProtocoloProcedimento(protocoloProcedimento);
            }

            GerenciadorBDConfigs.Instance.SessaoAtual().Merge(tmpProtocolo);
            return tmpProtocolo;
        }

        public void Excluir(Protocolo protocolo)
        {
            GerenciadorBDConfigs.Instance.SessaoAtual().Delete(protocolo);
        }

        public IList<Protocolo> ObterTodos()
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Protocolo));
            return criteria.List<Protocolo>() as List<Protocolo>;
        }

        public Protocolo ObterPorId(int id)
        {
            return GerenciadorBDConfigs.Instance.SessaoAtual().Get<Protocolo>(id);
        }

        public Protocolo ObterUltimoPorMotivoProtocolo(MotivoProtocolo motivoProtocolo)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Protocolo))
                .CreateAlias("MotivoProtocolo", "Motivo")
                .Add(Restrictions.Eq("Motivo.TipoMotivo", motivoProtocolo.TipoMotivo))
                .AddOrder(Order.Desc("Codigo"))
                .SetMaxResults(1);

            return criteria.UniqueResult<Protocolo>();
        }

        public int ObterUltimoIdCodigoInteiro()
        {
            string[] literal = new string[] 
                {"a","b","c","d","e","f","g","h","i","j"
                ,"l","m","n","o","p","q","r","s","t","u","v","x","z","y"
                ,"w"};

            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Protocolo)).SetMaxResults(1);

            for (int i = 0; i <= literal.Length - 1; i++)
            {
                criteria.Add(Restrictions.Not(Restrictions.Like("Codigo", literal[i], MatchMode.Anywhere)));
            }

            criteria.AddOrder(Order.Desc("ProtocoloId"));


            Protocolo protocolo = criteria.UniqueResult<Protocolo>();
            int ultimoCodigo = protocolo != null ? protocolo.ProtocoloId : 0;

            return ultimoCodigo;
        }

        public Protocolo ObterPorCodigo(string codigo)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Protocolo))
                .Add(Restrictions.Eq("Codigo", codigo));

            return criteria.UniqueResult<Protocolo>() as Protocolo;
        }
    }
}